package com.dbapp.shopping.service;

import com.dbapp.shopping.data.GoodOwnerRepository;
import com.dbapp.shopping.data.GoodRepository;
import com.dbapp.shopping.data.RecordRepository;
import com.dbapp.shopping.data.UserRepository;
import com.dbapp.shopping.domain.Good;
import com.dbapp.shopping.domain.GoodOwner;
import com.dbapp.shopping.domain.User;
import com.dbapp.shopping.domain.Record;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Optional;
import java.lang.Iterable;
import java.util.List;
import java.util.ArrayList;

import lombok.extern.slf4j.Slf4j;

@org.springframework.stereotype.Service
@Slf4j
public class ServiceImpl implements Service {

    private GoodRepository goodRepo;
    private GoodOwnerRepository goodOwnerRepo;
    private UserRepository userRepo;
    private RecordRepository recordRepo;

    @Autowired
    public ServiceImpl(GoodRepository goodRepo, GoodOwnerRepository goodOwnerRepo,
                       UserRepository userRepo, RecordRepository recordRepo) {
        this.goodRepo = goodRepo;
        this.userRepo = userRepo;
        this.goodOwnerRepo = goodOwnerRepo;
        this.recordRepo = recordRepo;
    }

    @Override
    public List<Good> getAllGoods() { return goodRepo.findAllGoods(); }

    @Override
    public Good saveGood(Good good) {
        return goodRepo.save(good);
    }

    @Override
    public Optional<Good> getGoodById(Long id) {
        return goodRepo.findById(id);
    }

    @Override
    public Optional<GoodOwner> getGoodOwnerByGood(Good good) { return goodOwnerRepo.findByGood(good); }

    @Override
    public Record saveRecord(Record record){return recordRepo.save(record);}

    @Override
    public List<Good> searchGoods(String query)
    {
        Iterable<Good> temp = goodRepo.findByNameLike("%" + query + "%");
        List<Good> res = new ArrayList<>();
        temp.forEach(i -> res.add(i));
        return res;
    }

    @Override
    public User saveUser(User user)
    {
        return userRepo.save(user);
    }

    @Override
    public Optional<User> getUserById(Long id)
    {
        return userRepo.findById(id);
    }

    @Override
    public List<Good> findGoodsByUser(User user)
    {
        List<GoodOwner> temp = goodOwnerRepo.findGoodsByUser(user);
        List<Good> res = new ArrayList<>();
        temp.forEach(i->res.add(i.getGood()));
        return res;
    }

    @Override
    public User findSeller(Good good)
    {
        Optional<GoodOwner> go = goodOwnerRepo.findByGood(good);
        User user = go.get().getUser();
        return user;
    }

    @Override
    public List<Record> findRecordsByUser(User user)
    {
        return recordRepo.findByUser(user);
    }

    @Override
    public void deleteGoodsById(Long id) {
        Optional<Good> good = goodRepo.findById(id);
        if (good.isPresent())
        {
            Good g = good.get();
            g.setDisplay(false);
            goodRepo.save(g);
        }
    }

    @Override
    public void deleteOrder(Long id)
    {
        Optional<Record> record = recordRepo.findById(id);
        if(record.isPresent())
        {
            Record r = record.get();
            r.setDisplay(false);
            recordRepo.save(r);
        }
    }

    @Override
    public User getUserByUsername(String username) { return userRepo.findByUsername(username); }

    @Override
    public GoodOwner saveGoodOwner(GoodOwner goodOwner) { return goodOwnerRepo.save(goodOwner); }

    @Override
    public Boolean isPrice(String price)
    {
        if(!price.matches("^\\d+(\\.\\d{1,2})?$"))
            return false;
        Double p = Double.valueOf(price);
        return (p > 0.0 && p <= 1000000.0);
    }

    @Override
    public Boolean isStock(String stock)
    {
        if(!stock.matches("^\\d+$"))
            return false;
        Long s = Long.valueOf(stock);
        return (s > 0 && s < 1000);
    }
}
